package org.Yiran.timetale_re.util.geometry;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.minecraft.core.Direction;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * BlockState解析器
 * <p>
 * 用于解析Minecraft的BlockState JSON文件，提取方块的朝向信息。
 * 支持从变体键和对象属性中解析Direction信息。
 * </p>
 * 
 * @author Yiran
 * @version 1.0
 */
public class BlockStateParser {
    
    // ==================== BlockState解析方法 ====================

    /**
     * 解析BlockState文件获取方块朝向信息
     * <p>
     * 从指定模组的资源中加载并解析BlockState JSON文件，
     * 提取所有变体的朝向信息并返回映射表。
     * </p>
     * 
     * @param modId 模组ID
     * @param blockName 方块名称
     * @return 朝向映射表，键为变体名称，值为对应的朝向
     */
    public static Map<String, Direction> parseBlockState(String modId, String blockName) {
        Map<String, Direction> facingMap = new HashMap<>();
        
        try {
            // 构建资源路径
            String resourcePath = "/assets/" + modId + "/blockstates/" + blockName + ".json";
            
            // 加载JSON文件
            InputStream inputStream = BlockStateParser.class.getResourceAsStream(resourcePath);
            if (inputStream == null) {
                System.err.println("无法找到blockstate文件: " + resourcePath);
                return facingMap;
            }
            
            // 解析JSON
            JsonObject jsonObject = JsonParser.parseReader(new InputStreamReader(inputStream)).getAsJsonObject();
            
            // 获取variants对象
            JsonObject variants = jsonObject.getAsJsonObject("variants");
            if (variants == null) {
                return facingMap;
            }
            
            // 遍历所有变体
            for (Map.Entry<String, JsonElement> entry : variants.entrySet()) {
                String variantKey = entry.getKey();
                JsonObject variantObj = entry.getValue().getAsJsonObject();
                
                // 解析朝向信息
                Direction facing = parseFacingFromVariant(variantKey, variantObj);
                if (facing != null) {
                    facingMap.put(variantKey, facing);
                }
            }
            
        } catch (Exception e) {
            System.err.println("解析BlockState时发生错误: " + e.getMessage());
        }
        
        return facingMap;
    }
    
    // ==================== 朝向解析辅助方法 ====================

    /**
     * 从变体键或对象中解析朝向
     * <p>
     * 尝试从变体键（如"facing=north"）或对象属性（如"y": 90）中解析出Direction。
     * 解析顺序为：键中的facing参数 -> Y轴旋转 -> X轴旋转 -> 默认朝向 NORTH。
     * </p>
     * 
     * @param variantKey 变体键字符串
     * @param variantObj 变体JSON对象
     * @return 解析出的朝向，如果无法解析则返回默认朝向 NORTH
     */
    private static Direction parseFacingFromVariant(String variantKey, JsonObject variantObj) {
        // 首先尝试从键中解析 (如 "facing=north")
        if (variantKey.contains("facing=")) {
            String[] parts = variantKey.split(",");
            for (String part : parts) {
                if (part.startsWith("facing=")) {
                    String facingStr = part.substring(7); // 移除 "facing=" 前缀
                    return stringToDirection(facingStr);
                }
            }
        }
        
        // 然后尝试从对象属性中解析
        if (variantObj.has("y")) {
            int yRotation = variantObj.get("y").getAsInt();
            return yRotationToDirection(yRotation);
        }
        
        if (variantObj.has("x")) {
            int xRotation = variantObj.get("x").getAsInt();
            return xRotationToDirection(xRotation);
        }
        
        return Direction.NORTH; // 默认朝向
    }
    
    /**
     * 将字符串转换为Direction
     * <p>
     * 将表示方向的字符串转换为对应的Direction枚举值。
     * 支持的基本方向包括：north, south, west, east, up, down。
     * </p>
     * 
     * @param facingStr 方向字符串
     * @return 对应的Direction枚举值，如果无法识别则返回 NORTH
     */
    private static Direction stringToDirection(String facingStr) {
        return switch (facingStr.toLowerCase()) {
            case "south" -> Direction.SOUTH;
            case "west" -> Direction.WEST;
            case "east" -> Direction.EAST;
            case "up" -> Direction.UP;
            case "down" -> Direction.DOWN;
            default -> Direction.NORTH;
        };
    }
    
    /**
     * 将Y轴旋转角度转换为Direction
     * <p>
     * 将Y轴旋转角度转换为对应的水平方向。
     * 角度对应关系：0° -> NORTH, 90° -> EAST, 180° -> SOUTH, 270° -> WEST。
     * </p>
     * 
     * @param yRotation Y轴旋转角度
     * @return 对应的Direction枚举值
     */
    private static Direction yRotationToDirection(int yRotation) {
        return switch (yRotation) {
            case 90 -> Direction.EAST;
            case 180 -> Direction.SOUTH;
            case 270 -> Direction.WEST;
            default -> Direction.NORTH;
        };
    }
    
    /**
     * 将X轴旋转角度转换为Direction
     * <p>
     * 将X轴旋转角度转换为对应的垂直方向。
     * 角度对应关系：-90° -> UP, 90° -> DOWN, 其他 -> NORTH。
     * </p>
     * 
     * @param xRotation X轴旋转角度
     * @return 对应的Direction枚举值
     */
    private static Direction xRotationToDirection(int xRotation) {
        return switch (xRotation) {
            case -90 -> Direction.UP;
            case 90 -> Direction.DOWN;
            default -> Direction.NORTH;
        };
    }
}